package ch.ethz.smseth;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;

public class RequestSender
{
	private static final String SMS_ETHZ_URL = "https://www.sms.ethz.ch/cgi-bin/sms/send.pl";
	private static int LIST_ORIGINATORS_TIMEOUT = 30000;
	
	public List<String> ListOriginators(String user, String pw) throws SenderException, ClientProtocolException, IOException, TrustServerException
	{
		HashMap<String, String> parameters = new HashMap<String, String>();
		parameters.put("action", "listoriginators");
		parameters.put("username", user);
		parameters.put("password", pw);
		ArrayList<String> result = DoRequest(SMS_ETHZ_URL, parameters, LIST_ORIGINATORS_TIMEOUT);
		
		if (result.size() == 0) throw new SenderException("No answer");
		
		int statusCode = Integer.parseInt(result.get(0).split(" ")[0]);
		if (statusCode != 200) throw new SenderException(result.get(0));
		
		ArrayList<String> originatorList = new ArrayList<String>();
		for (int i = 1; i < result.size(); i ++)
		{
			String[] splitted = result.get(i).split(",");
			if (splitted.length != 2) throw new SenderException("Invalid response syntax");
			originatorList.add(splitted[1]);
		}
		return originatorList;
	}
	
	public void Send(String user, String pw, String message, String originator, String number, int timeout) throws SenderException, ClientProtocolException, IOException, TrustServerException
	{
		HashMap<String, String> parameters = new HashMap<String, String>();
		parameters.put("action", "sendsms");
		parameters.put("username", user);
		parameters.put("password", pw);
		parameters.put("message", message);
		parameters.put("originator", originator);
		parameters.put("number", cleanUpNumber(number));
		ArrayList<String> result = DoRequest(SMS_ETHZ_URL, parameters, timeout);
		
		if (result.size() == 0) throw new SenderException("No answer");
		
		int statusCode = Integer.parseInt(result.get(0).split(" ")[0]);
		if (statusCode != 200)
		{
			throw new SenderException(result.get(0));
		}
	}
	
	private ArrayList<String> DoRequest(String url, HashMap<String, String> parameters, int timeout) throws SenderException, ClientProtocolException, IOException, TrustServerException
	{
		HttpParams params = new BasicHttpParams();
		HttpConnectionParams.setSoTimeout(params, timeout);
		HttpConnectionParams.setConnectionTimeout(params, timeout);
		HttpClient httpclient = (HttpClient) new TrustServerClient(443, params);
		HttpPost httppost = new HttpPost(SMS_ETHZ_URL);
		try
		{
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			
			for (String key : parameters.keySet())
			{
				nameValuePairs.add(new BasicNameValuePair(key, parameters.get(key)));
			}

			HttpEntity postEntity = new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
			httppost.setEntity(postEntity);

			HttpResponse response;
			response = httpclient.execute(httppost);
			HttpEntity responseEntity = response.getEntity();
			String result = EntityUtils.toString(responseEntity);

			ArrayList<String> resultArray = new ArrayList<String>();
			for (String line : result.split("\\n"))
			{
				resultArray.add(line);
			}
			return resultArray;
		} catch (ClientProtocolException e)
		{
			throw e;
		} catch (IOException e)
		{
			throw e;
		}
	}
	
	private String cleanUpNumber(String number)
	{
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < number.length(); i ++)
		{
			char c = number.charAt(i);
			if (('0' <= c && c <= '9') || c == '+') result.append(c);
		}
		return result.toString();
	}
}
